#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019-2025 A S Lewis
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.


"""Tartube main file."""


# Import Gtk modules
#   ...


# Import other modules
import os
import sys
import threading
import traceback
import importlib.util


# Add module directory to path to prevent import issues
spec = importlib.util.find_spec('tartube')
if spec is not None:
    sys.path.append(os.path.abspath(os.path.dirname(spec.origin)))


# Import our modules
import mainapp


# 'Global' variables
__packagename__ = 'tartube'
__version__ = '2.5.177'
__date__ = '27 Sep 2025'
__copyright__ = 'Copyright \xa9 2019-2025 A S Lewis'
__license__ = """
Copyright \xa9 2019-2025 A S Lewis.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option) any
later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
details.

You should have received a copy of the GNU Lesser General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
"""
__author_list__ = [
    'A S Lewis',
]
__credit_list__ = [
    # (This list is formatted to suit Gtk.AboutDialog)
    'Partially based on youtube-dl-gui by MrS0m30n3',
    'https://github.com/MrS0m30n3/youtube-dl-gui',
    'FFmpeg thumbnail code adapted from youtube-dl',
    'http://youtube-dl.org/',
    'FFmpeg options adapted from FFmpeg Command',
    'Line Wizard by AndreKR',
    'https://github.com/AndreKR/ffmpeg-command-line-wizard',
    'Upgraded Textview by Kevin Mehall',
    'https://kevinmehall.net/2010/pygtk_multi_select_drag_drop',
    'XDG support by Scott Stevenson',
    'https://pypi.org/project/xdg/',
]
__description__ = 'GUI front-end for youtube-dl, yt-dlp and\nother' \
+ ' compatible video downloaders'
__website__ = 'http://tartube.sourceforge.io'
__app_id__ = 'io.sourceforge.tartube'
__website_bugs__ = 'https://github.com/axcore/tartube'
__website_dev__ = 'http://raw.githubusercontent.com/axcore/tartube/master'
# Flag set to True if multiple instances of Tartube are allowed; False if
#   only a single instance is allowed
__multiple_instance_flag__ = True
# There are four executables; this default one, and three others used in
#   packaging. The others are identical, except for the values of these
#   variables
__pkg_install_flag__ = False
__pkg_strict_install_flag__ = False
__pkg_no_download_flag__ = False


# Uncaught exception handling
def setup_thread_excepthook():

    """Workaround for 'sys.excepthook' thread bug from:
    http://bugs.python.org/issue1230540

    Adapted from
    https://stackoverflow.com/questions/1643327/sys-excepthook-and-threading

    Call once from the main thread before creating any threads.
    """

    init_original = threading.Thread.__init__

    def init(self, *args, **kwargs):

        init_original(self, *args, **kwargs)
        run_original = self.run

        def run_with_except_hook(*args2, **kwargs2):
            try:
                run_original(*args2, **kwargs2)
            except Exception:
                sys.excepthook(*sys.exc_info())

        self.run = run_with_except_hook

    threading.Thread.__init__ = init


app = None
def handle_uncaught_exception(except_type, value, tb):

    """Intercepts uncaught exceptions, and diverts the message to the main
    window's Errors/Warnings tab, so ordinary users can actually see them and
    (hopefully) report them.

    Then raises the exception as normal.

    Adapted from
    https://dev.to/joshuaschlichting/
        catching-every-single-exception-with-python-40o3

    Args:
        except_type (type): Exception type
        value (TypeError): Exception value
        tb (traceback): Exception traceback

    """

    if app is not None:

        app.system_exception(
            except_type,
            value,
            '\n'.join(traceback.extract_tb(tb).format())
        )

    raise type(value)


setup_thread_excepthook()
sys.excepthook = handle_uncaught_exception


# Start Tartube
app = mainapp.TartubeApp()
app.run(sys.argv)
